/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace DaveSexton.DocProject.Sandcastle.BuildComponents
{
	public sealed class SandcastleBuildComponentManagerEditor : DocProjectOptionsDialogEditorBase<SandcastleProjectOptions, SandcastleBuildComponentDialog>
	{
		#region Public Properties
		#endregion

		#region Private / Protected
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="SandcastleBuildComponentManagerEditor" /> class.
		/// </summary>
		public SandcastleBuildComponentManagerEditor()
		{
		}
		#endregion

		#region Methods
		private static SandcastleBuildComponentManager GetManager(ITypeDescriptorContext context, object value)
		{
			// For components such as IfThenComponent, nested SandcastleBuildComponentManager instances are used to handle the nested components.
			SandcastleBuildComponentManager manager = value as SandcastleBuildComponentManager;

			if (manager == null)
			{
				// For components such as ForEachComponent, a single SandcastleBuildComponentManager instance is composited to handle nested components.
				SandcastleBuildComponent component = value as SandcastleBuildComponent;

				if (component != null && context != null)
				{
					TypeConverter converter = context.PropertyDescriptor.Converter;

					if (converter != null)
					{
						ICompositeBuildComponentManager composite = converter as ICompositeBuildComponentManager;

						if (composite != null)
							return composite.GetManager(context, component);
					}
				}
			}

			return manager;
		}

		protected override string GetPropertyName(SandcastleProjectOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			// If the editor is being invoked for a nested or composited SandcastleBuildComponentManager then the manager's reference to the root property name must be used.
			SandcastleBuildComponentManager manager = GetManager(context, value);

			if (manager == null)
				return base.GetPropertyName(options, context, provider, value);
			else
				return manager.RootPropertyName;
		}

		protected override SandcastleProjectOptions GetOptions(ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			// If the editor is being invoked for a nested or composited SandcastleBuildComponentManager then the manager's reference to SandcsatleProjectOptions must be used.
			SandcastleBuildComponentManager manager = GetManager(context, value);

			if (manager == null)
				return base.GetOptions(context, provider, value);
			else
				return manager.Options;
		}

		protected override SandcastleBuildComponentDialog CreateDialog(SandcastleProjectOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			if (options == null)
				throw new ArgumentNullException("options");

			SandcastleBuildComponentManager manager = GetManager(context, value);
			manager.NotifyChanging();

			return new SandcastleBuildComponentDialog(manager);
		}

		protected override bool HandleChanges(SandcastleProjectOptions options, SandcastleBuildComponentDialog form, System.Windows.Forms.DialogResult result)
		{
			if (options == null)
				throw new ArgumentNullException("options");

			SandcastleBuildComponentManager manager = form.Manager;

			if (result == System.Windows.Forms.DialogResult.OK)
			{
				manager.CommitChanges();
				manager.NotifyChanged(true);
				return true;
			}
			else
			{
				manager.CancelChanges();
				return false;
			}
		}

		protected override object GetValue(SandcastleProjectOptions options, SandcastleBuildComponentDialog form, System.Windows.Forms.DialogResult result)
		{
			return form.Manager;
		}
		#endregion
	}
}
